package nl.altenpts.vokad;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.security.KeyPair;
import java.util.Random;

import nl.altenpts.net.NetReactor;
import nl.altenpts.net.kad.Callback;
import nl.altenpts.net.kad.Kademlia;
import nl.altenpts.net.kad.Value;

/**
 * 
 * @author phub4r
 * VodkadJava is java implementation (Vodkad is android based)
 */
public class VokadJava {

	/**
	 * Default number (constant) to start port numbering
	 */
	public final static int BASEPORT = 2345;
	
	/**
	 * 
	 * @param args
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public static void main(String args[]) throws IOException, InterruptedException {
		
		InetAddress localHostAddress = InetAddress.getByName("10.0.0.240");
	
		Kademlia[] kads = new Kademlia[40];
		NetReactor[] reactors = new NetReactor[5];
		
		for(int i = 0; i < reactors.length; i++) {
			reactors[i] = new NetReactor();
			Thread t = new Thread(reactors[i]);
			t.setDaemon(true);
			t.start();
		}
				
		ObjectInputStream objin = new ObjectInputStream(new FileInputStream("1000keys"));

		
		InetSocketAddress address;
		for(int i = 0; i < kads.length;i++) {
			try {
				KeyPair keys = (KeyPair) objin.readObject();
				address = new InetSocketAddress(localHostAddress, BASEPORT+i);
				kads[i] = new Kademlia(reactors[i % reactors.length], keys, address );
			} catch (Exception e) {
				e.printStackTrace();
			}			
		}
		
		for(int i = 0; i < kads.length ; i++) {
			for(int j = 0; j < kads.length; j++) {
				if(i != j) {
					kads[i].addNode(kads[j].getAddress());
				}
			}
		}
		
//		for(int i = 1; i < kads.length; i++) {
//			kads[i].bootstrap(kads[i - 1].getAddress());
//			Thread.sleep(3600000);
//		}

		//System.out.println("Routing tables are ready");
		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));

		//stdin.readLine();
		//for(int i = 0; i < kads.length; i++) {
		//	kads[i].writeTable();
		//}
		
		Random rand = new Random();
		
				
		while(true) {
			String line = stdin.readLine();
			if(line.contains("=")) {
				int pos = line.indexOf('=');
				String key = line.substring(0, pos);
				String value = line.substring(pos + 1);
				kads[rand.nextInt(kads.length)].set(key.getBytes("utf-8"), value.getBytes("utf-8"), new Callback() {

					public void onFinished() {
						System.out.println("Value is set");
					}

					public void onResponse(Object response) {
						// ignore
					}
					
				});
			} else {
				/* get operation */
				kads[rand.nextInt(kads.length)].get(line.getBytes("utf-8"), new Callback() {

					public void onFinished() {
						System.out.println("Response finished");
					}

					public void onResponse(Object response) {
						Value v = (Value) response;
						
						try {
							String s = new String(v.getValue(), "utf-8");
							System.out.println("Response: " + s);
						} catch (UnsupportedEncodingException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				});
			}
		}
	}
}
